import { isObject } from 'lodash-es'
import { getCustomComDesignInfo } from '../axios'
import { useComDesignStoreWithOut } from '../../index'

import { BwNodeCustomComInfoModel } from './model'
import {
  getNodeComAttrs,
  BwComTypeEnum,
  BwCustomComSoltTypeEnum,
  BwCustomComFrontTypeEnum,
  BwCustomComPropDataTypeEnum,
  BwCustomComNodeIfFromTypeEnum,
  BwCustomComNodeForFromTypeEnum,
  BwCustomComNodeAttrFromTypeEnum,
  BwCustomComNodeAttrDataTypeEnum,
  BwCustomComEmitParamDataTypeEnum,
  BwCustomComSlotParamDataTypeEnum,
  BwCustomComTrendSlotVarFromTypeEnum,
  BwCustomComNodeIfJsExpParamFromTypeEnum,
  BwCustomComNodeIfJsExpParamDataTypeEnum,
  BwCustomComNodeForJsExpParamFromTypeEnum,
  BwCustomComNodeForJsExpParamDataTypeEnum,
  BwCustomComNodeAttrJsExpParamFromTypeEnum,
  BwCustomComNodeAttrJsExpParamDataTypeEnum,
  BwCustomComNodeEventCallbackParamFromTypeEnum,
  type BwCustomComStructModel,
  type BwCustomComEmitInfoModel,
  type BwCustomComSlotInfoModel,
  type BwCustomComPropInfoModel,
  type BwCustomComNodeAttrModel,
  type BwCustomComSlotParmsModel,
  type BwCustomComEmitParmsModel,
  type BwCustomComDesignInfoModel,
  type BwCustomComNodeIfInfoModel,
  type BwCustomComNodeForInfoModel,
  type BwCustomComNodeEventInfoModel,
  type BwCustomComTrendsSlotInfoModel,
  type BwCustomComNodeIfJsExpParamModel,
  type BwCustomComNodeForJsExpParamModel,
  type BwCustomComConventionSlotInfoModel,
  type BwCustomComNodeAttrJsExpParamModel,
  type BwCustomComNodeEvenJsExpParamModel,
  type BwCustomComNodeEnableSlotInfoModel,
  type BwCustomComNodeEventCallbackParamInfoModel,
} from '@bitwit/base-com-render'

import {
  BwRenderComTypeEnum,
  BwRenderCustomComSoltTypeEnum,
  BwRenderCustomComFrontTypeEnum,
  BwRenderCustomComPropDataTypeEnum,
  BwRenderCustomComNodeAttrFromTypeEnum,
  BwRenderCustomComNodeAttrDataTypeEnum,
  BwRenderCustomComEmitParamDataTypeEnum,
  BwRenderCustomComSlotParamDataTypeEnum,
  BwRenderCustomComEventParamDataTypeEnum,
  BwRenderCustomComNodeIfValueFromTypeEnum,
  BwRenderCustomComNodeForValueFromTypeEnum,
  BwRenderCustomComTrendSlotVarFromTypeEnum,
  BwRenderCustomComNodeIfJsExpParamDataTypeEnum,
  BwRenderCustomComNodeIfJsExpParamFromTypeEnum,
  BwRenderCustomComNodeForJsExpParamDataTypeEnum,
  BwRenderCustomComNodeForJsExpParamFromTypeEnum,
  BwRenderCustomComNodeAttrJsExpParamDataTypeEnum,
  BwRenderCustomComNodeAttrJsExpParamFromTypeEnum,
  BwRenderCustomComNodeEventCallbackParamFromTypeEnum,
  type BwRenderCustomComStructModel,
  type BwRenderCustomComSlotParmsModel,
  type BwRenderCustomComPropInfoModel,
  type BwRenderCustomComSlotInfoModel,
  type BwRenderCustomComEmitInfoModel,
  type BwRenderCustomComNodeAttrModel,
  type BwRenderCustomComEmitParmsModel,
  type BwRenderCustomComRenderInfoModel,
  type BwRenderCustomComNodeIfInfoModel,
  type BwRenderCustomComRelyComInfoModel,
  type BwRenderCustomComNodeForInfoModel,
  type BwRenderCustomComNodeEventInfoModel,
  type BwRenderCustomComNodeEventParmsModel,
  type BwRenderCustomComTrendsSlotInfoModel,
  type BwRenderCustomComNodeIfJsExpParamModel,
  type BwRenderCustomComNodeForJsExpParamModel,
  type BwRenderCustomComNodeAttrJsExpParamModel,
  type BwRenderCustomComNodeEvenJsExpParamModel,
  type BwRenderCustomComConventionSlotInfoModel,
  type BwRenderCustomComEnableSlotInfoModel,
  type BwRenderCustomComNodeEventCallbackParamInfoModel,
} from '@bitwit/utils-render-model'

/** 加载DOM树种使用到的自定义组件 */
export function loadingRelyCurtomCom(designInfo: BwCustomComDesignInfoModel) {
  return new Promise<any>((resolve, reject) => {
    const designStore = useComDesignStoreWithOut()

    const curStructs = designInfo.structs
    const curtomComs: Array<BwNodeCustomComInfoModel> = []
    const comInfo = designStore.curCustomComRenderInfo ?? {}

    const getCurtomComList = (structs: BwCustomComStructModel[]) => {
      if (Array.isArray(structs) && structs.length) {
        structs.forEach((item) => {
          const { comAppCode, comName, comType, children } = item
          if (comType === BwComTypeEnum.custom) {
            if (
              comAppCode &&
              !(comName in comInfo) &&
              !curtomComs.find(
                (n) => n.appId === comAppCode && n.comCode === comName
              )
            ) {
              curtomComs.push({ appId: comAppCode, comCode: comName })
            }
          }

          if (isObject(children)) {
            Object.values(children).forEach((child) => {
              getCurtomComList(child)
            })
          }
        })
      }
    }
    getCurtomComList(curStructs[BwCustomComFrontTypeEnum.pc])
    getCurtomComList(curStructs[BwCustomComFrontTypeEnum.ios])
    getCurtomComList(curStructs[BwCustomComFrontTypeEnum.android])

    if (Array.isArray(curtomComs) && curtomComs.length) {
      Promise.all(
        curtomComs.map((n) => {
          return getCustomComDesignInfo(n.appId, n.comCode)
        })
      )
        .then(() => resolve(true))
        .catch(() => reject())
    } else {
      resolve(true)
    }
  })
}

/** 获取渲染信息 */
export function getRenderInfo(
  designInfo: BwCustomComDesignInfoModel
): BwRenderCustomComRenderInfoModel {
  const curStructs = designInfo.structs
  const structInfo = {} as Record<
    BwRenderCustomComFrontTypeEnum,
    BwRenderCustomComStructModel[]
  >
  const relyInfo = {} as Record<
    BwRenderCustomComFrontTypeEnum,
    BwRenderCustomComRelyComInfoModel[]
  >
  Object.keys(curStructs).forEach((key: BwRenderCustomComFrontTypeEnum) => {
    relyInfo[key] = []
    structInfo[key] = getStructsInfo(curStructs[key], relyInfo[key])
  })

  const renderInfo: BwRenderCustomComRenderInfoModel = {
    setup: designInfo.setup,
    comCss: designInfo.comCss,
    comCode: designInfo.comCode,
    comName: designInfo.comName,
    version: designInfo.version,
    designVersion: designInfo.designVersion,

    structs: structInfo,
    relyComList: relyInfo,

    emits: createComEmits(designInfo.emits),
    comProps: createComProps(designInfo.comProps),
    comSlots: createComSlotList(designInfo.comSlots ?? undefined),
  }
  return renderInfo
}

function createComSlotList(
  data?: Array<BwCustomComSlotInfoModel>
): Array<BwRenderCustomComSlotInfoModel> | null {
  if (Array.isArray(data) && data.length) {
    const list: Array<BwRenderCustomComSlotInfoModel> = []

    data.forEach((item) => {
      list.push({
        slotType: toComSlotType(item.slotType),
        trendsSlotInfo: cretaeComTrendsSlotInfo(item.trendsSlotInfo),
        conventionSlotInfo: cretaeComConventionSlotInfo(
          item.conventionSlotInfo
        ),
      })
    })

    return list
  } else {
    return null
  }
}
/** 生成组件动态插槽信息 */
function cretaeComTrendsSlotInfo(
  data?: BwCustomComTrendsSlotInfoModel
): BwRenderCustomComTrendsSlotInfoModel | undefined {
  if (data) {
    return {
      slotCode: data.slotCode,
      logicCode: data.logicCode,
      logicName: data.logicName,
      comVarName: data.comVarName,
      comPorpName: data.comPorpName,
      slotParams: createComTrendsSlotParams(data.slotParams),
      trendVarFrom: toComTrendsSlotVarFrom(data.trendVarFrom),
    }
  } else {
    return undefined
  }
}
/** 生成组件动态插槽参数信息 */
function createComTrendsSlotParams(
  data: Array<BwCustomComSlotParmsModel>
): Array<BwRenderCustomComSlotParmsModel> {
  const list: Array<BwRenderCustomComSlotParmsModel> = []
  if (Array.isArray(data) && data.length) {
    data.forEach((n) => {
      list.push({
        remark: n.remark,
        paramKey: n.paramKey,
        paramName: n.paramName,
        paramDataType: toComSlotParamDataType(n.paramDataType),
      })
    })
  }
  return list
}
/** 生成组件常态插槽信息 */
function cretaeComConventionSlotInfo(
  data?: BwCustomComConventionSlotInfoModel
): BwRenderCustomComConventionSlotInfoModel | undefined {
  if (data) {
    return {
      slotName: data.slotName,
      slotCode: data.slotCode,
      slotParams: createComConventionSlotParams(data.slotParams),
    }
  } else {
    return undefined
  }
}
function createComConventionSlotParams(
  data?: Array<BwCustomComSlotParmsModel>
): Array<BwRenderCustomComSlotParmsModel> {
  const list: Array<BwRenderCustomComSlotParmsModel> = []
  if (Array.isArray(data) && data.length) {
    data.forEach((n) => {
      list.push({
        remark: n.remark,
        paramKey: n.paramKey,
        paramName: n.paramName,
        paramDataType: toComSlotParamDataType(n.paramDataType),
      })
    })
  }
  return list
}

/** 转换组件插槽类型 */
function toComSlotType(
  type: BwCustomComSoltTypeEnum | null
): BwRenderCustomComSoltTypeEnum {
  switch (type) {
    case BwCustomComSoltTypeEnum.trends: {
      return BwRenderCustomComSoltTypeEnum.trends
    }
    case BwCustomComSoltTypeEnum.convention: {
      return BwRenderCustomComSoltTypeEnum.convention
    }
    default: {
      return BwRenderCustomComSoltTypeEnum.convention
    }
  }
}
/** 转换组件动态插槽变量来源类型 */
function toComTrendsSlotVarFrom(
  type: BwCustomComTrendSlotVarFromTypeEnum
): BwRenderCustomComTrendSlotVarFromTypeEnum {
  switch (type) {
    case BwCustomComTrendSlotVarFromTypeEnum.comProps: {
      return BwRenderCustomComTrendSlotVarFromTypeEnum.comProps
    }
    case BwCustomComTrendSlotVarFromTypeEnum.comVar: {
      return BwRenderCustomComTrendSlotVarFromTypeEnum.comVar
    }
    default: {
      return BwRenderCustomComTrendSlotVarFromTypeEnum.comVar
    }
  }
}
/** 转换组件插槽参数数据类型 */
function toComSlotParamDataType(
  type: BwCustomComSlotParamDataTypeEnum
): BwRenderCustomComSlotParamDataTypeEnum {
  switch (type) {
    case BwCustomComSlotParamDataTypeEnum.array: {
      return BwRenderCustomComSlotParamDataTypeEnum.array
    }
    case BwCustomComSlotParamDataTypeEnum.boolean: {
      return BwRenderCustomComSlotParamDataTypeEnum.boolean
    }
    case BwCustomComSlotParamDataTypeEnum.number: {
      return BwRenderCustomComSlotParamDataTypeEnum.number
    }
    case BwCustomComSlotParamDataTypeEnum.object: {
      return BwRenderCustomComSlotParamDataTypeEnum.object
    }
    case BwCustomComSlotParamDataTypeEnum.string: {
      return BwRenderCustomComSlotParamDataTypeEnum.string
    }
    default: {
      return BwRenderCustomComSlotParamDataTypeEnum.string
    }
  }
}

/** 生成外放属性配置 */
function createComProps(
  data: Nullable<BwCustomComPropInfoModel[]>
): Array<BwRenderCustomComPropInfoModel> | null {
  let props: Array<BwRenderCustomComPropInfoModel> | null = null

  if (Array.isArray(data) && data.length) {
    props = []
    data.forEach((item: BwCustomComPropInfoModel) => {
      // @ts-ignore
      props.push({
        key: item.key,
        name: item.name,
        remark: item.remark,
        isModel: !!item.isModel,
        isRequire: !!item.isRequire,
        defaultValue: item.defaultValue,
        constValueSetCom: item.constValueSetCom,
        dataType: toComPropDataType(item.dataType),
        constValueSetComProps: item.constValueSetComProps,
        defaultValueDataType: toComPropDefaultValueDataType(
          item.defaultValueDataType ?? null
        ),
      })
    })
  }

  return props
}
/** 转数据组件外放属性数据类型 */
function toComPropDataType(
  data: Array<BwCustomComPropDataTypeEnum> | null
): Array<BwRenderCustomComPropDataTypeEnum> | null {
  if (Array.isArray(data) && data.length) {
    const list: Array<BwRenderCustomComPropDataTypeEnum> = []
    data.forEach((item) => {
      switch (item) {
        case BwCustomComPropDataTypeEnum.array: {
          list.push(BwRenderCustomComPropDataTypeEnum.array)
          break
        }
        case BwCustomComPropDataTypeEnum.boolean: {
          list.push(BwRenderCustomComPropDataTypeEnum.boolean)
          break
        }
        case BwCustomComPropDataTypeEnum.function: {
          list.push(BwRenderCustomComPropDataTypeEnum.function)
          break
        }
        case BwCustomComPropDataTypeEnum.number: {
          list.push(BwRenderCustomComPropDataTypeEnum.number)
          break
        }
        case BwCustomComPropDataTypeEnum.object: {
          list.push(BwRenderCustomComPropDataTypeEnum.object)
          break
        }
        case BwCustomComPropDataTypeEnum.string: {
          list.push(BwRenderCustomComPropDataTypeEnum.string)
          break
        }
        default: {
          list.push(BwRenderCustomComPropDataTypeEnum.string)
          break
        }
      }
    })

    return list
  } else {
    return null
  }
}
/** 转数据组件外放属性数据类型 */
function toComPropDefaultValueDataType(
  type: BwCustomComPropDataTypeEnum | null
): BwRenderCustomComPropDataTypeEnum | null {
  switch (type) {
    case BwCustomComPropDataTypeEnum.array: {
      return BwRenderCustomComPropDataTypeEnum.array
    }
    case BwCustomComPropDataTypeEnum.boolean: {
      return BwRenderCustomComPropDataTypeEnum.boolean
    }
    case BwCustomComPropDataTypeEnum.function: {
      return BwRenderCustomComPropDataTypeEnum.function
    }
    case BwCustomComPropDataTypeEnum.number: {
      return BwRenderCustomComPropDataTypeEnum.number
    }
    case BwCustomComPropDataTypeEnum.object: {
      return BwRenderCustomComPropDataTypeEnum.object
    }
    case BwCustomComPropDataTypeEnum.string: {
      return BwRenderCustomComPropDataTypeEnum.string
    }
    default: {
      return null
    }
  }
}

/** 生成外放事件配置 */
function createComEmits(
  data: Nullable<BwCustomComEmitInfoModel[]>
): Array<BwRenderCustomComEmitInfoModel> | null {
  let emits: Array<BwRenderCustomComEmitInfoModel> | null = null

  if (Array.isArray(data) && data.length) {
    emits = []
    data.forEach((item: BwCustomComEmitInfoModel) => {
      // @ts-ignore
      emits.push({
        key: item.key,
        name: item.name,
        isModel: !!item.isModel,
        desc: item.desc,
        params: !item.params
          ? undefined
          : item.params.map((n): BwRenderCustomComEmitParmsModel => {
              return {
                paramKey: n.paramKey,
                paramName: n.paramName,
                remark: n.remark,
                paramDataType: toMeitParamDataType(n.paramDataType),
              }
            }),
      })
    })
  }

  return emits
}

/** 解析 DOM 树 */
function getStructsInfo(
  structs: Array<BwCustomComStructModel>,
  relyList: Array<BwRenderCustomComRelyComInfoModel>
) {
  const list: Array<BwRenderCustomComStructModel> = []
  if (Array.isArray(structs) && structs.length) {
    structs.forEach((item) => {
      const { comName, comType, comAppCode, children } = item

      const relyInfo = relyList.find((n) => n.comCode === comName)
      if (!relyInfo) {
        relyList.push({
          comCode: comName,
          comType: toComType(comType),
          comAppCode: comAppCode ?? undefined,
        })
      }

      const childNodes: Record<string, Array<BwRenderCustomComStructModel>> = {}
      if (children) {
        Object.keys(children).forEach((name) => {
          childNodes[name] = getStructsInfo(children[name], relyList)
        })
      }

      list.push({
        comName,
        css: item.css,
        style: item.style,
        nodeId: item.nodeId,
        nodeName: item.nodeName,
        comAppCode: item.comAppCode,
        parentNodeId: item.parentNodeId,
        parentNodeSlotCode: item.parentNodeSlotCode,

        comType: toComType(comType),
        events: createNodeEventInfo(item.events ?? null),
        nodeIfInfo: createNodeIfInfo(item.nodeIfInfo ?? null),
        attrs: createNodeAttrInfo(comName, comType, item.attrs),
        nodeForInfo: createNodeForInfo(item.nodeForInfo ?? null),
        enableSlotList: createNodeEnableSlotList(item.enableSlotList),

        children: !children ? null : childNodes,
      })
    })
  }

  return list
}
/** 转换组件类型 */
function toComType(type: BwComTypeEnum) {
  switch (type) {
    case BwComTypeEnum.ant: {
      return BwRenderComTypeEnum.ant
    }
    case BwComTypeEnum.bw: {
      return BwRenderComTypeEnum.bw
    }
    case BwComTypeEnum.custom: {
      return BwRenderComTypeEnum.custom
    }
    case BwComTypeEnum.html: {
      return BwRenderComTypeEnum.html
    }
    case BwComTypeEnum.vant: {
      return BwRenderComTypeEnum.vant
    }
    case BwComTypeEnum.vue: {
      return BwRenderComTypeEnum.vue
    }
    case BwComTypeEnum.vxe: {
      return BwRenderComTypeEnum.vxe
    }
    default: {
      return BwRenderComTypeEnum.ant
    }
  }
}

/** 生成节点元素开启插槽列表 */
function createNodeEnableSlotList(
  data: Array<BwCustomComNodeEnableSlotInfoModel> | null
): Array<BwRenderCustomComEnableSlotInfoModel> | null {
  if (Array.isArray(data) && data.length) {
    const list: Array<BwRenderCustomComEnableSlotInfoModel> = []
    data.forEach((item) => {
      list.push({
        visible: item.visible,
        slotType: toComSlotType(item.slotType),
        trendsSlotInfo: cretaeComTrendsSlotInfo(item.trendsSlotInfo),
        conventionSlotInfo: cretaeComConventionSlotInfo(
          item.conventionSlotInfo
        ),
      })
    })
    return list
  } else {
    return null
  }
}

function createNodeAttrIsModelStateFun(
  comName: string,
  comType: BwComTypeEnum
) {
  if (comType === BwComTypeEnum.custom) {
    const designStore = useComDesignStoreWithOut()
    const comInfo = designStore.curCustomComRenderInfo ?? {}
    if (isObject(comInfo)) {
      const curCom = comInfo[comName] ?? {}
      const curComAttrs = curCom.comProps ?? []
      return (attrName: string) => {
        const item = curComAttrs.find((n) => n.key === attrName)
        return !!item?.isModel
      }
    }
  } else {
    const curComAttrs = getNodeComAttrs(comName)
    return (attrName: string) => {
      const item = curComAttrs.find((n) => n.key === attrName)
      return !!item?.isModel
    }
  }
  return (_attrName: string) => false
}

function createNodeAttrInfo(
  comName: string,
  comType: BwComTypeEnum,
  data: Record<string, BwCustomComNodeAttrModel> | null
): Record<string, BwRenderCustomComNodeAttrModel> {
  const attrs: Record<string, BwRenderCustomComNodeAttrModel> = {}
  if (data) {
    const getIsModelStateFun = createNodeAttrIsModelStateFun(comName, comType)

    Object.keys(data).forEach((key) => {
      const info = data[key]
      attrs[key] = {
        isModel: getIsModelStateFun(key),
        constValue: info.constValue,
        comVarName: info.comVarName,
        slotVarName: info.slotVarName,
        forVarName: info.forVarName,
        comPropsName: info.comPropsName,
        jsExpBodyLogic: info.jsExpBodyLogic,
        valueFromType: toNodeAttrValueFromType(info.valueFromType),
        valueDataType: toNodeAttrValueDataType(info.valueDataType),
        jsExpParams: createNodeAttrValueJsExpParams(info.jsExpParams ?? null),
      }
    })
  }

  return attrs
}
function createNodeEventInfo(
  data: Array<BwCustomComNodeEventInfoModel> | null
): Array<BwRenderCustomComNodeEventInfoModel> | null {
  if (Array.isArray(data) && data.length) {
    const list: Array<BwRenderCustomComNodeEventInfoModel> = []
    data.forEach((item) => {
      list.push({
        eventName: item.eventName,
        eventCode: item.eventCode,
        callbackFun: item.callbackFun,
        eventParams: createNodeEventParamInfo(item.eventParams ?? null),
        callbackFunParams: createNodeEventCallbackFunParamInfo(
          item.callbackFunParams ?? null
        ),
      })
    })
    return list
  } else {
    return null
  }
}
function createNodeEventParamInfo(
  data: Array<BwCustomComEmitParmsModel> | null
): Array<BwRenderCustomComNodeEventParmsModel> | undefined {
  if (data) {
    const list: Array<BwRenderCustomComNodeEventParmsModel> = []
    data.forEach((n) => {
      list.push({
        paramKey: n.paramKey,
        paramName: n.paramName,
        paramDataType: toNodeEventParamDataType(n.paramDataType),
        remark: n.remark,
      })
    })
    return list
  } else {
    return undefined
  }
}
function toNodeEventParamDataType(
  type: BwCustomComEmitParamDataTypeEnum
): BwRenderCustomComEventParamDataTypeEnum {
  switch (type) {
    case BwCustomComEmitParamDataTypeEnum.array: {
      return BwRenderCustomComEventParamDataTypeEnum.array
    }
    case BwCustomComEmitParamDataTypeEnum.boolean: {
      return BwRenderCustomComEventParamDataTypeEnum.boolean
    }
    case BwCustomComEmitParamDataTypeEnum.number: {
      return BwRenderCustomComEventParamDataTypeEnum.number
    }
    case BwCustomComEmitParamDataTypeEnum.object: {
      return BwRenderCustomComEventParamDataTypeEnum.number
    }
    case BwCustomComEmitParamDataTypeEnum.string: {
      return BwRenderCustomComEventParamDataTypeEnum.string
    }
    default: {
      return BwRenderCustomComEventParamDataTypeEnum.object
    }
  }
}

function createNodeEventCallbackFunParamInfo(
  data: Array<BwCustomComNodeEventCallbackParamInfoModel> | null
): Array<BwRenderCustomComNodeEventCallbackParamInfoModel> | undefined {
  if (data) {
    const list: Array<BwRenderCustomComNodeEventCallbackParamInfoModel> = []
    data.forEach((n) => {
      list.push({
        paramCode: n.paramCode,
        paramName: n.paramCode,
        constValue: n.constValue,
        comVarName: n.comVarName,
        comPropsName: n.comPropsName,
        eventParamName: n.eventParamName,
        nodeForVarName: n.nodeForVarName,
        jsExpBodyLogic: n.jsExpBodyLogic,

        paramFrom: toNodeEventCallbackParamFromType(n.paramFrom),
        paramDataType: toNodeEventCallbackParamDataType(n.paramDataType),
        jsExpParams: createNodeEventCallbackParamJsExpParam(
          n.jsExpParams ?? null
        ),
      })
    })

    return list
  } else {
    return undefined
  }
}
/** 转换节点远程事件回调参数来源类型 */
function toNodeEventCallbackParamFromType(
  type: BwCustomComNodeEventCallbackParamFromTypeEnum
): BwRenderCustomComNodeEventCallbackParamFromTypeEnum {
  switch (type) {
    case BwCustomComNodeEventCallbackParamFromTypeEnum.JSExpression: {
      return BwRenderCustomComNodeEventCallbackParamFromTypeEnum.JSExpression
    }
    case BwCustomComNodeEventCallbackParamFromTypeEnum.comProp: {
      return BwRenderCustomComNodeEventCallbackParamFromTypeEnum.comProp
    }
    case BwCustomComNodeEventCallbackParamFromTypeEnum.comVar: {
      return BwRenderCustomComNodeEventCallbackParamFromTypeEnum.comVar
    }
    case BwCustomComNodeEventCallbackParamFromTypeEnum.const: {
      return BwRenderCustomComNodeEventCallbackParamFromTypeEnum.const
    }
    case BwCustomComNodeEventCallbackParamFromTypeEnum.event: {
      return BwRenderCustomComNodeEventCallbackParamFromTypeEnum.event
    }
    case BwCustomComNodeEventCallbackParamFromTypeEnum.forVar: {
      return BwRenderCustomComNodeEventCallbackParamFromTypeEnum.forVar
    }
    case BwCustomComNodeEventCallbackParamFromTypeEnum.slotVar: {
      return BwRenderCustomComNodeEventCallbackParamFromTypeEnum.slotVar
    }
    default: {
      return BwRenderCustomComNodeEventCallbackParamFromTypeEnum.const
    }
  }
}
/** 转换节点远程事件回调参数数据类型 */
function toNodeEventCallbackParamDataType(
  type: BwCustomComEmitParamDataTypeEnum
): BwRenderCustomComEventParamDataTypeEnum {
  switch (type) {
    case BwCustomComEmitParamDataTypeEnum.array: {
      return BwRenderCustomComEventParamDataTypeEnum.array
    }
    case BwCustomComEmitParamDataTypeEnum.boolean: {
      return BwRenderCustomComEventParamDataTypeEnum.boolean
    }
    case BwCustomComEmitParamDataTypeEnum.number: {
      return BwRenderCustomComEventParamDataTypeEnum.number
    }
    case BwCustomComEmitParamDataTypeEnum.object: {
      return BwRenderCustomComEventParamDataTypeEnum.object
    }
    case BwCustomComEmitParamDataTypeEnum.string: {
      return BwRenderCustomComEventParamDataTypeEnum.string
    }
    default: {
      return BwRenderCustomComEventParamDataTypeEnum.string
    }
  }
}

function createNodeEventCallbackParamJsExpParam(
  data: Array<BwCustomComNodeEvenJsExpParamModel> | null
): Array<BwRenderCustomComNodeEvenJsExpParamModel> | null {
  if (Array.isArray(data) && data.length) {
    const list: Array<BwRenderCustomComNodeEvenJsExpParamModel> = []
    data.forEach((n) => {
      list.push({
        key: n.key,
        name: n.key,
        isRequire: !!n.isRequire,
        defaultValue: n.defaultValue,
        paramDataType: toNodeEventCallbackParamJsExpParamDataType(
          n.paramDataType ?? null
        ),
        defaultValueDataType:
          toNodeEventCallbackParamJsExpParamDefaultValueDataType(
            n.defaultValueDataType ?? null
          ),
        remark: n.remark,
      })
    })

    return list
  } else {
    return null
  }
}
function toNodeEventCallbackParamJsExpParamDefaultValueDataType(
  type: BwCustomComEmitParamDataTypeEnum | null
): BwRenderCustomComEventParamDataTypeEnum | null {
  switch (type) {
    case BwCustomComEmitParamDataTypeEnum.array: {
      return BwRenderCustomComEventParamDataTypeEnum.array
    }
    case BwCustomComEmitParamDataTypeEnum.boolean: {
      return BwRenderCustomComEventParamDataTypeEnum.boolean
    }
    case BwCustomComEmitParamDataTypeEnum.number: {
      return BwRenderCustomComEventParamDataTypeEnum.number
    }
    case BwCustomComEmitParamDataTypeEnum.object: {
      return BwRenderCustomComEventParamDataTypeEnum.object
    }
    case BwCustomComEmitParamDataTypeEnum.string: {
      return BwRenderCustomComEventParamDataTypeEnum.string
    }
    default: {
      return null
    }
  }
}

function toNodeEventCallbackParamJsExpParamDataType(
  types: Array<BwCustomComEmitParamDataTypeEnum> | null
): Array<BwRenderCustomComEventParamDataTypeEnum> | null {
  if (Array.isArray(types) && types.length) {
    const list: Array<BwRenderCustomComEventParamDataTypeEnum> = []
    types.forEach((type) => {
      switch (type) {
        case BwCustomComEmitParamDataTypeEnum.array: {
          list.push(BwRenderCustomComEventParamDataTypeEnum.array)
          break
        }
        case BwCustomComEmitParamDataTypeEnum.boolean: {
          list.push(BwRenderCustomComEventParamDataTypeEnum.boolean)
          break
        }
        case BwCustomComEmitParamDataTypeEnum.number: {
          list.push(BwRenderCustomComEventParamDataTypeEnum.number)
          break
        }
        case BwCustomComEmitParamDataTypeEnum.object: {
          list.push(BwRenderCustomComEventParamDataTypeEnum.object)
          break
        }
        case BwCustomComEmitParamDataTypeEnum.string: {
          list.push(BwRenderCustomComEventParamDataTypeEnum.string)
          break
        }
      }
    })

    return list
  } else {
    return null
  }
}

function createNodeIfInfo(
  data: BwCustomComNodeIfInfoModel | null
): BwRenderCustomComNodeIfInfoModel | undefined {
  if (data) {
    const resData: BwRenderCustomComNodeIfInfoModel = {
      visible: !!data.visible,
      constValue: data.constValue,
      comVarName: data.comVarName,
      comPropsName: data.comPropsName,
      jsExpBodyLogic: data.jsExpBodyLogic,
      conditionVarFrom: toNodeIfVarFromType(data.conditionVarFrom),
      jsExpParams: createNodeIfJsExpParams(data.jsExpParams ?? null),
    }
    return resData
  } else {
    return undefined
  }
}
function createNodeForInfo(
  data: BwCustomComNodeForInfoModel | null
): BwRenderCustomComNodeForInfoModel | undefined {
  if (data) {
    const resData: BwRenderCustomComNodeForInfoModel = {
      visible: !!data.visible,
      constValue: data.constValue,
      comVarName: data.comVarName,
      comPropsName: data.comPropsName,
      jsExpBodyLogic: data.jsExpBodyLogic,
      forVarFrom: toNodeForVarFromType(data.forVarFrom),
      jsExpParams: createNodeForJsExpParams(data.jsExpParams ?? null),
    }
    return resData
  } else {
    return undefined
  }
}

function toMeitParamDataType(
  type: BwCustomComEmitParamDataTypeEnum
): BwRenderCustomComEmitParamDataTypeEnum {
  switch (type) {
    case BwCustomComEmitParamDataTypeEnum.array: {
      return BwRenderCustomComEmitParamDataTypeEnum.array
    }
    case BwCustomComEmitParamDataTypeEnum.boolean: {
      return BwRenderCustomComEmitParamDataTypeEnum.boolean
    }
    case BwCustomComEmitParamDataTypeEnum.number: {
      return BwRenderCustomComEmitParamDataTypeEnum.number
    }
    case BwCustomComEmitParamDataTypeEnum.object: {
      return BwRenderCustomComEmitParamDataTypeEnum.number
    }
    case BwCustomComEmitParamDataTypeEnum.string: {
      return BwRenderCustomComEmitParamDataTypeEnum.string
    }
    default: {
      return BwRenderCustomComEmitParamDataTypeEnum.object
    }
  }
}
function toNodeAttrValueFromType(
  type: BwCustomComNodeAttrFromTypeEnum
): BwRenderCustomComNodeAttrFromTypeEnum {
  switch (type) {
    case BwCustomComNodeAttrFromTypeEnum.comProps: {
      return BwRenderCustomComNodeAttrFromTypeEnum.comProps
    }
    case BwCustomComNodeAttrFromTypeEnum.comVar: {
      return BwRenderCustomComNodeAttrFromTypeEnum.comVar
    }
    case BwCustomComNodeAttrFromTypeEnum.constValue: {
      return BwRenderCustomComNodeAttrFromTypeEnum.constValue
    }
    case BwCustomComNodeAttrFromTypeEnum.forVar: {
      return BwRenderCustomComNodeAttrFromTypeEnum.forVar
    }
    case BwCustomComNodeAttrFromTypeEnum.slotVar: {
      return BwRenderCustomComNodeAttrFromTypeEnum.slotVar
    }
    case BwCustomComNodeAttrFromTypeEnum.JSExpression: {
      return BwRenderCustomComNodeAttrFromTypeEnum.JSExpression
    }
    default: {
      return BwRenderCustomComNodeAttrFromTypeEnum.constValue
    }
  }
}
function toNodeAttrValueDataType(
  type: BwCustomComNodeAttrDataTypeEnum | null
): BwRenderCustomComNodeAttrDataTypeEnum {
  switch (type) {
    case BwCustomComNodeAttrDataTypeEnum.array: {
      return BwRenderCustomComNodeAttrDataTypeEnum.array
    }
    case BwCustomComNodeAttrDataTypeEnum.boolean: {
      return BwRenderCustomComNodeAttrDataTypeEnum.boolean
    }
    case BwCustomComNodeAttrDataTypeEnum.number: {
      return BwRenderCustomComNodeAttrDataTypeEnum.number
    }
    case BwCustomComNodeAttrDataTypeEnum.object: {
      return BwRenderCustomComNodeAttrDataTypeEnum.object
    }
    case BwCustomComNodeAttrDataTypeEnum.string: {
      return BwRenderCustomComNodeAttrDataTypeEnum.string
    }
    case BwCustomComNodeAttrDataTypeEnum.function: {
      return BwRenderCustomComNodeAttrDataTypeEnum.function
    }
    default: {
      return BwRenderCustomComNodeAttrDataTypeEnum.string
    }
  }
}

function toNodeIfVarFromType(
  type?: BwCustomComNodeIfFromTypeEnum
): BwRenderCustomComNodeIfValueFromTypeEnum {
  switch (type) {
    case BwCustomComNodeIfFromTypeEnum.comProps: {
      return BwRenderCustomComNodeIfValueFromTypeEnum.comProps
    }
    case BwCustomComNodeIfFromTypeEnum.comVar: {
      return BwRenderCustomComNodeIfValueFromTypeEnum.comVar
    }
    case BwCustomComNodeIfFromTypeEnum.constValue: {
      return BwRenderCustomComNodeIfValueFromTypeEnum.constValue
    }
    case BwCustomComNodeIfFromTypeEnum.forVar: {
      return BwRenderCustomComNodeIfValueFromTypeEnum.forVar
    }
    case BwCustomComNodeIfFromTypeEnum.JSExpression: {
      return BwRenderCustomComNodeIfValueFromTypeEnum.JSExpression
    }
    default: {
      return BwRenderCustomComNodeIfValueFromTypeEnum.constValue
    }
  }
}
function toNodeForVarFromType(
  type?: BwCustomComNodeForFromTypeEnum
): BwRenderCustomComNodeForValueFromTypeEnum {
  switch (type) {
    case BwCustomComNodeForFromTypeEnum.comProps: {
      return BwRenderCustomComNodeForValueFromTypeEnum.comProps
    }
    case BwCustomComNodeForFromTypeEnum.comVar: {
      return BwRenderCustomComNodeForValueFromTypeEnum.comVar
    }
    case BwCustomComNodeForFromTypeEnum.constValue: {
      return BwRenderCustomComNodeForValueFromTypeEnum.constValue
    }
    case BwCustomComNodeForFromTypeEnum.forVar: {
      return BwRenderCustomComNodeForValueFromTypeEnum.forVar
    }
    case BwCustomComNodeForFromTypeEnum.JSExpression: {
      return BwRenderCustomComNodeForValueFromTypeEnum.JSExpression
    }
    default: {
      return BwRenderCustomComNodeForValueFromTypeEnum.constValue
    }
  }
}

function createNodeAttrValueJsExpParams(
  data: Nullable<BwCustomComNodeAttrJsExpParamModel[]>
): Array<BwRenderCustomComNodeAttrJsExpParamModel> | null {
  if (Array.isArray(data) && data.length) {
    const list: Array<BwRenderCustomComNodeAttrJsExpParamModel> = []
    data.forEach((item) => {
      list.push({
        key: item.key,
        name: item.name,
        isRequire: item.isRequire,
        constValue: item.paramDataType,
        comVarName: item.comVarName,
        comPropsName: item.comPropsName,
        nodeForVarName: item.nodeForVarName,
        remark: item.remark,
        paramDataType: toNodeAttrValueJsExpParamDataType(item.paramDataType),
        paramFromType: toNodeAttrValueJsExpParamFromType(item.paramFromType),
      })
    })
    return list
  } else {
    return null
  }
}
function toNodeAttrValueJsExpParamDataType(
  type: BwCustomComNodeAttrJsExpParamDataTypeEnum
): BwRenderCustomComNodeAttrJsExpParamDataTypeEnum {
  switch (type) {
    case BwCustomComNodeAttrJsExpParamDataTypeEnum.array: {
      return BwRenderCustomComNodeAttrJsExpParamDataTypeEnum.array
    }
    case BwCustomComNodeAttrJsExpParamDataTypeEnum.boolean: {
      return BwRenderCustomComNodeAttrJsExpParamDataTypeEnum.boolean
    }
    case BwCustomComNodeAttrJsExpParamDataTypeEnum.function: {
      return BwRenderCustomComNodeAttrJsExpParamDataTypeEnum.function
    }
    case BwCustomComNodeAttrJsExpParamDataTypeEnum.number: {
      return BwRenderCustomComNodeAttrJsExpParamDataTypeEnum.number
    }
    case BwCustomComNodeAttrJsExpParamDataTypeEnum.object: {
      return BwRenderCustomComNodeAttrJsExpParamDataTypeEnum.object
    }
    case BwCustomComNodeAttrJsExpParamDataTypeEnum.string: {
      return BwRenderCustomComNodeAttrJsExpParamDataTypeEnum.string
    }
    default: {
      return BwRenderCustomComNodeAttrJsExpParamDataTypeEnum.string
    }
  }
}
function toNodeAttrValueJsExpParamFromType(
  type: BwCustomComNodeAttrJsExpParamFromTypeEnum
): BwRenderCustomComNodeAttrJsExpParamFromTypeEnum {
  switch (type) {
    case BwCustomComNodeAttrJsExpParamFromTypeEnum.comVar: {
      return BwRenderCustomComNodeAttrJsExpParamFromTypeEnum.comVar
    }
    case BwCustomComNodeAttrJsExpParamFromTypeEnum.comProps: {
      return BwRenderCustomComNodeAttrJsExpParamFromTypeEnum.comProps
    }
    case BwCustomComNodeAttrJsExpParamFromTypeEnum.constValue: {
      return BwRenderCustomComNodeAttrJsExpParamFromTypeEnum.constValue
    }
    case BwCustomComNodeAttrJsExpParamFromTypeEnum.forVar: {
      return BwRenderCustomComNodeAttrJsExpParamFromTypeEnum.forVar
    }
    case BwCustomComNodeAttrJsExpParamFromTypeEnum.JSExpression: {
      return BwRenderCustomComNodeAttrJsExpParamFromTypeEnum.JSExpression
    }
    default: {
      return BwRenderCustomComNodeAttrJsExpParamFromTypeEnum.constValue
    }
  }
}

function createNodeIfJsExpParams(
  data: Nullable<BwCustomComNodeIfJsExpParamModel[]>
): Array<BwRenderCustomComNodeIfJsExpParamModel> | null {
  if (Array.isArray(data) && data.length) {
    const list: Array<BwRenderCustomComNodeIfJsExpParamModel> = []
    data.forEach((item) => {
      list.push({
        key: item.key,
        name: item.name,
        isRequire: item.isRequire,
        constValue: item.paramDataType,
        comVarName: item.comVarName,
        comPropsName: item.comPropsName,
        nodeForVarName: item.nodeForVarName,
        remark: item.remark,
        paramDataType: toNodeIfJsExpParamDataType(item.paramDataType),
        paramFromType: toNodeIfJsExpParamFromType(item.paramFromType),
      })
    })
    return list
  } else {
    return null
  }
}
function toNodeIfJsExpParamDataType(
  type: BwCustomComNodeIfJsExpParamDataTypeEnum
): BwRenderCustomComNodeIfJsExpParamDataTypeEnum {
  switch (type) {
    case BwCustomComNodeIfJsExpParamDataTypeEnum.array: {
      return BwRenderCustomComNodeIfJsExpParamDataTypeEnum.array
    }
    case BwCustomComNodeIfJsExpParamDataTypeEnum.boolean: {
      return BwRenderCustomComNodeIfJsExpParamDataTypeEnum.boolean
    }
    case BwCustomComNodeIfJsExpParamDataTypeEnum.function: {
      return BwRenderCustomComNodeIfJsExpParamDataTypeEnum.function
    }
    case BwCustomComNodeIfJsExpParamDataTypeEnum.number: {
      return BwRenderCustomComNodeIfJsExpParamDataTypeEnum.number
    }
    case BwCustomComNodeIfJsExpParamDataTypeEnum.object: {
      return BwRenderCustomComNodeIfJsExpParamDataTypeEnum.object
    }
    case BwCustomComNodeIfJsExpParamDataTypeEnum.string: {
      return BwRenderCustomComNodeIfJsExpParamDataTypeEnum.string
    }
    default: {
      return BwRenderCustomComNodeIfJsExpParamDataTypeEnum.string
    }
  }
}
function toNodeIfJsExpParamFromType(
  type: BwCustomComNodeIfJsExpParamFromTypeEnum
): BwRenderCustomComNodeIfJsExpParamFromTypeEnum {
  switch (type) {
    case BwCustomComNodeIfJsExpParamFromTypeEnum.comVar: {
      return BwRenderCustomComNodeIfJsExpParamFromTypeEnum.comVar
    }
    case BwCustomComNodeIfJsExpParamFromTypeEnum.comProps: {
      return BwRenderCustomComNodeIfJsExpParamFromTypeEnum.comProps
    }
    case BwCustomComNodeIfJsExpParamFromTypeEnum.constValue: {
      return BwRenderCustomComNodeIfJsExpParamFromTypeEnum.constValue
    }
    case BwCustomComNodeIfJsExpParamFromTypeEnum.forVar: {
      return BwRenderCustomComNodeIfJsExpParamFromTypeEnum.forVar
    }
    case BwCustomComNodeIfJsExpParamFromTypeEnum.JSExpression: {
      return BwRenderCustomComNodeIfJsExpParamFromTypeEnum.JSExpression
    }
    default: {
      return BwRenderCustomComNodeIfJsExpParamFromTypeEnum.constValue
    }
  }
}

function createNodeForJsExpParams(
  data: Nullable<BwCustomComNodeForJsExpParamModel[]>
): Array<BwRenderCustomComNodeForJsExpParamModel> | null {
  if (Array.isArray(data) && data.length) {
    const list: Array<BwRenderCustomComNodeForJsExpParamModel> = []
    data.forEach((item) => {
      list.push({
        key: item.key,
        name: item.name,
        isRequire: item.isRequire,
        constValue: item.paramDataType,
        comVarName: item.comVarName,
        comPropsName: item.comPropsName,
        nodeForVarName: item.nodeForVarName,
        remark: item.remark,
        paramDataType: toNodeForJsExpParamDataType(item.paramDataType),
        paramFromType: toNodeForJsExpParamFromType(item.paramFromType),
      })
    })
    return list
  } else {
    return null
  }
}
function toNodeForJsExpParamDataType(
  type: BwCustomComNodeForJsExpParamDataTypeEnum
): BwRenderCustomComNodeForJsExpParamDataTypeEnum {
  switch (type) {
    case BwCustomComNodeForJsExpParamDataTypeEnum.array: {
      return BwRenderCustomComNodeForJsExpParamDataTypeEnum.array
    }
    case BwCustomComNodeForJsExpParamDataTypeEnum.boolean: {
      return BwRenderCustomComNodeForJsExpParamDataTypeEnum.boolean
    }
    case BwCustomComNodeForJsExpParamDataTypeEnum.function: {
      return BwRenderCustomComNodeForJsExpParamDataTypeEnum.function
    }
    case BwCustomComNodeForJsExpParamDataTypeEnum.number: {
      return BwRenderCustomComNodeForJsExpParamDataTypeEnum.number
    }
    case BwCustomComNodeForJsExpParamDataTypeEnum.object: {
      return BwRenderCustomComNodeForJsExpParamDataTypeEnum.object
    }
    case BwCustomComNodeForJsExpParamDataTypeEnum.string: {
      return BwRenderCustomComNodeForJsExpParamDataTypeEnum.string
    }
    default: {
      return BwRenderCustomComNodeForJsExpParamDataTypeEnum.string
    }
  }
}
function toNodeForJsExpParamFromType(
  type: BwCustomComNodeForJsExpParamFromTypeEnum
): BwRenderCustomComNodeForJsExpParamFromTypeEnum {
  switch (type) {
    case BwCustomComNodeForJsExpParamFromTypeEnum.comVar: {
      return BwRenderCustomComNodeForJsExpParamFromTypeEnum.comVar
    }
    case BwCustomComNodeForJsExpParamFromTypeEnum.comProps: {
      return BwRenderCustomComNodeForJsExpParamFromTypeEnum.comProps
    }
    case BwCustomComNodeForJsExpParamFromTypeEnum.constValue: {
      return BwRenderCustomComNodeForJsExpParamFromTypeEnum.constValue
    }
    case BwCustomComNodeForJsExpParamFromTypeEnum.forVar: {
      return BwRenderCustomComNodeForJsExpParamFromTypeEnum.forVar
    }
    case BwCustomComNodeForJsExpParamFromTypeEnum.JSExpression: {
      return BwRenderCustomComNodeForJsExpParamFromTypeEnum.JSExpression
    }
    default: {
      return BwRenderCustomComNodeForJsExpParamFromTypeEnum.constValue
    }
  }
}
